#include <hip/hip_runtime.h>
#include <iostream>

#define BUF_WIDTH 1024
#define BUF_HEIGHT 1024
#define BUF_SIZE BUF_WIDTH *BUF_HEIGHT
#define TIMES 3  // 测试次数
#define CHECK_MINSIZE 1024  //hipprof默认检测最小的内存大小

#define nBytes BUF_WIDTH * BUF_HEIGHT

using namespace std;

int main(int argc, char *argv[]) {
  int free_flag = 0;
	string test_func_idx = "12345";  // 默认5个函数都执行
	int size = nBytes;
	int times = TIMES;
  for (int i = 1; i < argc; i++) {
    if (argv[i][0] == '-' && argv[i][1] == '-') {
      // 处理长命令行参数
      std::string option = argv[i];
      std::string value;
      if (i + 1 < argc && argv[i + 1][0] != '-') {
        value = argv[++i];
      }
      // 根据选项执行相应的操作
      if (option == "--func_idx") {
        test_func_idx = value;
      } else if (option == "--free") {
        free_flag = stoi(value);
      } else if (option == "--size") {
        size = stoi(value);
      } else if (option == "--times") {
        times = stoi(value);
      } else {
        std::cerr << "Unknown option: " << option << std::endl;
      }
    } else {
      // 处理短命令行参数或参数值
    }
  }

  hipDeviceProp_t devProp;
  hipGetDeviceProperties(&devProp, 0);
  std::cout << "dcu" << 0 << ": " << devProp.name << std::endl;

  hipError_t ret = hipSuccess;

  void *ptr1 = nullptr;
  ret = hipHostMalloc((void **)&ptr1, BUF_SIZE * 3);
  if (ret != hipSuccess) {
    return -1;
  }
  if (free_flag) {
    hipHostFree(ptr1);
  }

  void *ptr2 = nullptr;
  ret = hipMalloc((void **)&ptr2, BUF_SIZE * 5);
  if (ret != hipSuccess) {
    return -2;
  }
  if (free_flag) {
    hipFree(ptr2);
  }
  // hipFree(ptr2);

  void *ptr3 = nullptr;
  size_t pitch = 0;
  ret = hipMallocPitch((void **)&ptr3, &pitch, BUF_WIDTH, BUF_HEIGHT * 5);
  if (ret != hipSuccess) {
    return -3;
  }
  if (free_flag) {
    hipFree(ptr3);
  }
  // hipFree(ptr3);

  void *ptr4 = nullptr;
  uint32_t elementSizeBytes = 4;
  ret = hipMemAllocPitch(&ptr4, &pitch, BUF_WIDTH, BUF_HEIGHT * 5,
                         elementSizeBytes);
  if (ret != hipSuccess) {
    return -4;
  }
  if (free_flag) {
    hipFree(ptr4);
  }
  // hipFree(ptr4);

  hipPitchedPtr pitchedPtr;
  hipExtent hextent;
  hextent.width = BUF_WIDTH;
  hextent.height = BUF_HEIGHT;
  hextent.depth = 5;
  ret = hipMalloc3D(&pitchedPtr, hextent);
  if (ret != hipSuccess) {
    return -5;
  }
  if (free_flag) {
    hipFree(pitchedPtr.ptr);
  }
  // hipFree(pitchedPtr.ptr);

  hipChannelFormatDesc channelDesc = hipCreateChannelDesc(
      elementSizeBytes * 8, 0, 0, 0, hipChannelFormatKindUnsigned);
  hipArray *mallocArray;
  ret = hipMallocArray(&mallocArray, &channelDesc, BUF_WIDTH, BUF_HEIGHT,
                       hipArrayDefault);
  if (ret != hipSuccess) {
    return -6;
  }
  if (free_flag) {
    hipFreeArray(mallocArray);
  }
  // hipFreeArray(mallocArray);

  hipArray *malloc3DArray;
  hipChannelFormatDesc channelDesc2 =
      hipCreateChannelDesc(32, 0, 0, 0, hipChannelFormatKindFloat);
  ret =
      hipMalloc3DArray(&malloc3DArray, &channelDesc2, hextent, hipArrayDefault);
  if (ret != hipSuccess) {
    return -7;
  }
  if (free_flag) {
    hipFreeArray(malloc3DArray);
  }
  // hipFreeArray(malloc3DArray);

  hipMipmappedArray_t mipmappedArray;
  hipChannelFormatDesc channelDesc3 =
      hipCreateChannelDesc(32, 0, 0, 0, hipChannelFormatKindFloat);
  ret = hipMallocMipmappedArray(&mipmappedArray, &channelDesc3, hextent, 0, 0);
  if (ret != hipSuccess) {
    return -8;
  }
  if (free_flag) {
    hipFreeMipmappedArray(mipmappedArray);
  }
  // hipFreeMipmappedArray(mipmappedArray);

  return 0;
}
